import 'package:hive/hive.dart';

part 'message.g.dart';

@HiveType(typeId: 5)
enum MessageType {
  @HiveField(0)
  text,
  @HiveField(1)
  image,
  @HiveField(2)
  gift,
}

@HiveType(typeId: 4)
class MessageEntity extends HiveObject {
  @HiveField(0)
  final String id;

  @HiveField(1)
  final String senderId;

  @HiveField(2)
  final String receiverId;

  @HiveField(3)
  final String content;

  @HiveField(4)
  final MessageType type;

  @HiveField(5)
  final DateTime timestamp;

  @HiveField(6)
  final bool isRead;

  MessageEntity({
    required this.id,
    required this.senderId,
    required this.receiverId,
    required this.content,
    required this.type,
    required this.timestamp,
    this.isRead = false,
  });

  factory MessageEntity.fromJson(Map<String, dynamic> json) {
    return MessageEntity(
      id: json['id'],
      senderId: json['senderId'],
      receiverId: json['receiverId'],
      content: json['content'],
      type: MessageType.values[json['type']],
      timestamp: DateTime.parse(json['timestamp']),
      isRead: json['isRead'] ?? false,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'senderId': senderId,
      'receiverId': receiverId,
      'content': content,
      'type': type.index,
      'timestamp': timestamp.toIso8601String(),
      'isRead': isRead,
    };
  }

  MessageEntity copyWith({
    String? id,
    String? senderId,
    String? receiverId,
    String? content,
    MessageType? type,
    DateTime? timestamp,
    bool? isRead,
  }) {
    return MessageEntity(
      id: id ?? this.id,
      senderId: senderId ?? this.senderId,
      receiverId: receiverId ?? this.receiverId,
      content: content ?? this.content,
      type: type ?? this.type,
      timestamp: timestamp ?? this.timestamp,
      isRead: isRead ?? this.isRead,
    );
  }

  @override
  String toString() {
    return 'MessageEntity(id: $id, senderId: $senderId, receiverId: $receiverId, content: $content, type: $type, timestamp: $timestamp, isRead: $isRead)';
  }

  static final List<MessageEntity> defaultMessages = [
    MessageEntity(
      id: '1',
      senderId: '1',
      receiverId: '2',
      content: 'Hi Mark! How was your day?',
      type: MessageType.text,
      timestamp: DateTime.now().subtract(const Duration(hours: 2)),
      isRead: true,
    ),
    MessageEntity(
      id: '2',
      senderId: '2',
      receiverId: '1',
      content: 'Not bad! Just saw your post, it\'s amazing!',
      type: MessageType.text,
      timestamp: DateTime.now().subtract(const Duration(hours: 1, minutes: 50)),
      isRead: true,
    ),
    MessageEntity(
      id: '3',
      senderId: '1',
      receiverId: '2',
      content: 'assets/image/post1.png',
      type: MessageType.image,
      timestamp: DateTime.now().subtract(const Duration(hours: 1, minutes: 30)),
      isRead: true,
    ),
    MessageEntity(
      id: '4',
      senderId: '2',
      receiverId: '1',
      content: 'Wow, this photo is beautiful! Where did you take it?',
      type: MessageType.text,
      timestamp: DateTime.now().subtract(const Duration(hours: 1, minutes: 20)),
      isRead: false,
    ),

    MessageEntity(
      id: '5',
      senderId: '3',
      receiverId: '1',
      content: 'Hello Kina, your sharing really touched me',
      type: MessageType.text,
      timestamp: DateTime.now().subtract(const Duration(minutes: 45)),
      isRead: false,
    ),
    MessageEntity(
      id: '6',
      senderId: '1',
      receiverId: '3',
      content: 'Thank you for your attention! Happy to share positive energy',
      type: MessageType.text,
      timestamp: DateTime.now().subtract(const Duration(minutes: 30)),
      isRead: true,
    ),
    MessageEntity(
      id: '7',
      senderId: '3',
      receiverId: '1',
      content: 'assets/image/post5.png',
      type: MessageType.image,
      timestamp: DateTime.now().subtract(const Duration(minutes: 25)),
      isRead: false,
    ),

    MessageEntity(
      id: '8',
      senderId: '2',
      receiverId: '3',
      content: 'Hey buddy, feeling a bit lost lately...',
      type: MessageType.text,
      timestamp: DateTime.now().subtract(const Duration(minutes: 15)),
      isRead: true,
    ),
    MessageEntity(
      id: '9',
      senderId: '3',
      receiverId: '2',
      content: 'I understand how you feel, we all have moments like this',
      type: MessageType.text,
      timestamp: DateTime.now().subtract(const Duration(minutes: 10)),
      isRead: false,
    ),
    MessageEntity(
      id: '10',
      senderId: '3',
      receiverId: '2',
      content: 'assets/image/emotions/happy.gif',
      type: MessageType.image,
      timestamp: DateTime.now().subtract(const Duration(minutes: 5)),
      isRead: false,
    ),
  ];

  static List<MessageEntity> getMessagesByUserId(String userId) {
    return defaultMessages
        .where(
          (message) =>
              message.senderId == userId || message.receiverId == userId,
        )
        .toList();
  }

  static List<MessageEntity> getConversation(String userId1, String userId2) {
    return defaultMessages
        .where(
          (message) =>
              (message.senderId == userId1 && message.receiverId == userId2) ||
              (message.senderId == userId2 && message.receiverId == userId1),
        )
        .toList()
      ..sort((a, b) => a.timestamp.compareTo(b.timestamp));
  }

  static List<MessageEntity> getLatestConversations(String userId) {
    Map<String, MessageEntity> latestMessages = {};

    for (var message in defaultMessages) {
      String partnerId;
      if (message.senderId == userId) {
        partnerId = message.receiverId;
      } else if (message.receiverId == userId) {
        partnerId = message.senderId;
      } else {
        continue;
      }

      if (!latestMessages.containsKey(partnerId) ||
          message.timestamp.isAfter(latestMessages[partnerId]!.timestamp)) {
        latestMessages[partnerId] = message;
      }
    }

    return latestMessages.values.toList()
      ..sort((a, b) => b.timestamp.compareTo(a.timestamp));
  }

  static int getUnreadCount(String userId) {
    return defaultMessages
        .where((message) => message.receiverId == userId && !message.isRead)
        .length;
  }
}
